
# -*- coding: utf-8 -*-
import json
import sqlite3
import paho.mqtt.client as mqtt
from setting import *

class SubscriptionServer:

    def __init__(self, subscription_topic, publish_topic) -> None:

        self.publish_topic = publish_topic
        
        self.subscription_topic = subscription_topic

        self.init_db()


    def init_db(self):

        try:
            conn = sqlite3.connect('sqlite3.db')

            # 创建一个游标对象
            cursor = conn.cursor()


            with open("db.sql", encoding="utf-8") as f:

                # 执行语句
                cursor.executescript(f.read())


        except Exception as e:


            if not "UNIQUE" in str(e):
                logger.error(f"接收心任务初始化数据库时失败： {str(e)}")

                raise Exception(f"接收心任务初始化数据库时失败： {str(e)}")
            

        else:

            # 提交事务
            conn.commit()

            # 关闭连接
            conn.close()

            logger.info("初始化接收心任务数据库")

        finally:

            conn.close()



    def connect_mqtt(self):

        client = mqtt.Client()

        # 指定回调函数
        client.on_connect = self.on_connect
        client.on_message = self.on_message

        # 建立连接
        client.connect(MQTT_DATA_CENTER_HOST, MQTT_DATA_CENTER_PORT, 60)

        # 发布消息
        client.publish(self.publish_topic ,payload=f'主站：{MAC}---连接成功',qos=0)

        client.loop_forever()


    def on_connect(self, client, userdata, flags, rc):
        '''连接成功回调'''
        logger.info('Connected with result code '+str(rc))
        client.subscribe(self.subscription_topic)

    def on_message(self, client, userdata, msg):
        '''消息接收回调'''

        parse_msg = json.loads(msg.payload.decode())

        if self.insert_info_to_sqlite3_db(parse_msg):

            # 构造回调消息
            callback_msg = {
                "type": "callback",
                "data": {
                    "task_type": parse_msg["task_type"],
                    "task_id": parse_msg["task_id"],
                    "task_status": "receive",
                    "notes": None,
                    "result": None
                }
            }
            
            # 将回调消息转换为 JSON 字符串
            callback_msg_json = json.dumps(callback_msg)

            # 发送回调消息
            client.publish(self.publish_topic, callback_msg_json)

            logger.info(f"publish_topic: {self.publish_topic} 回调成功: 任务ID: {parse_msg['task_id']}")

        

    ##################### 任务处理函数 #######################
    def insert_info_to_sqlite3_db(self, task_info):
        #SQL 插入语句
        sql = '''INSERT INTO tasks (task_type, task_id, data_json) VALUES (?, ?, ?)'''

        try:
            conn = sqlite3.connect('sqlite3.db')

            # 创建一个游标对象
            cursor = conn.cursor()

            task_json = json.dumps(task_info)

            logger.info(f"task_info: {task_info}")

            # 执行插入语句
            cursor.execute(sql, (task_info["task_type"], task_info["task_id"], task_json))

        except sqlite3.IntegrityError as e:

            if e.args[0].startswith("UNIQUE"):

                logger.info(f"接收心任务插入数据库: 任务ID: {task_info['task_id']} 已存在")

                return 1
            else:

                logger.error(f"接收心任务插入数据库时失败： {e.args}")

                return 0
            
        except Exception as e:

            logger.error(f"接收心任务插入数据库时失败： {e.args}")

            return 0

        else:

            # 提交事务
            conn.commit()

            logger.info(f"Topic: {self.subscription_topic}--{task_info}")

            return 1

        finally:
            # 关闭游标
            cursor.close()
            # 关闭连接
            conn.close()

            
if __name__ == "__main__":

    r = SubscriptionServer(subscription_topic=MQTT_DATA_CENTER_PUBLISH_TOPIC, publish_topic=MQTT_DATA_CENTER_SUBSCRIPTION_TOPIC)

    r.connect_mqtt()